﻿namespace DataStructure;

public static class MyExtentionMethod
{
    public static void Print(this Array arrayNd)
    {
        int N = arrayNd.Rank;
        int[] lens = new int[N - 1];
        int p = 1;
        for (int i = 1; i < N; i++)
        {
            lens[i - 1] = arrayNd.GetLength(i);
            p = p * lens[i - 1];
        }

        if (N == 1)
        {
            foreach (var item in arrayNd)
            {
                Console.Write(item + " ");
            }
            Console.WriteLine();
        }
        else
        {
            object[] arr = new object[arrayNd.Length];
            ArrayMap.CopyArrayFromNdTo1d(arrayNd, arr);

            for (int i = 0; i < arrayNd.GetLength(0); i++)
            {
                Array array = Array.CreateInstance(typeof(object), lens);

                ArraySegment<object> segment = new ArraySegment<object>(arr, i * p, p);
                ArrayMap.CopyArrayFrom1dToNd(segment.ToArray(), array);

                Console.WriteLine(i + ", ");
                Print(array);
            }
        }
    }
    //从1维映射到n维，动态规划算法
    public static void CopyArrayFrom1dToNd(this Array array1d, Array arrayNd)
    {
        int N = arrayNd.Rank; //N：目标数组的维数。

        int[] T = new int[N]; //T：存储目标数组对应元素各个下标的计算表达式分母值。
        T[N - 1] = 1; //求最后一个下标时，分母值为1；
        for (int k = N - 2; k >= 0; k--)
        {
            T[k] = arrayNd.GetLength(k + 1) * T[k + 1];
        }

        for (int i = 0; i < array1d.Length; i++)
        {
            int[] J = new int[N]; //J：目标数组对应元素的下标数组，存储该元素的各维的下标值。
            for (int k = 0; k < N; k++)
            {
                J[k] = i % (arrayNd.GetLength(k) * T[k]) / T[k];
            }

            arrayNd.SetValue(array1d.GetValue(i), J);
        }
    }

    //从n维映射到1维，动态规划算法
    public static void CopyArrayFromNdTo1d(this Array arrayNd, Array array1d)
    {
        int N = arrayNd.Rank; //N：目标数组的维数。

        int[] T = new int[N]; //T：存储目标数组对应元素各个下标的计算表达式分母值。
        T[N - 1] = 1; //求最后一个下标时，分母值为1；
        for (int k = N - 2; k >= 0; k--)
        {
            T[k] = arrayNd.GetLength(k + 1) * T[k + 1];
        }

        for (int i = 0; i < array1d.Length; i++)
        {
            int[] J = new int[N]; //J：目标数组对应元素的下标数组，存储该元素的各维的下标值。
            for (int k = 0; k < N; k++)
            {
                J[k] = i % (arrayNd.GetLength(k) * T[k]) / T[k];
            }

            array1d.SetValue(arrayNd.GetValue(J), i);
        }
    }

}
